package cn.itsource.org.service.impl;

import cn.itsource.basic.eum.ShopStateEnum;
import cn.itsource.basic.query.BaseQuery;
import cn.itsource.basic.util.BaiduAuditUtils;
import cn.itsource.basic.util.BusinessException;
import cn.itsource.basic.util.EmailUtil;
import cn.itsource.basic.util.PageList;
import cn.itsource.org.domain.Employee;
import cn.itsource.org.domain.Shop;
import cn.itsource.org.domain.ShopAuditLog;
import cn.itsource.org.dto.ShopAdminDto;
import cn.itsource.org.dto.ShopAuditDto;
import cn.itsource.org.dto.ShopSettlementDto;
import cn.itsource.org.mapper.EmployeeMapper;
import cn.itsource.org.mapper.ShopAuditLogMapper;
import cn.itsource.org.mapper.ShopMapper;
import cn.itsource.org.service.EmployeeService;
import cn.itsource.org.service.IShopService;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author itsource
 * @since 2023-02-28
 */
@Service
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private ShopAuditLogMapper auditLogMapper;




    /**
     * 店铺入驻
     *
     * @param dto
     */
    @Override
    public void settlement(ShopSettlementDto dto) {
        // 参数校验 ctrl+alt+m
        this.verify(dto);
        // 保存数据
        this.save(dto);
    }

    /**
     * 审核通过
     * @param dto
     */
    @Override
    public void auditPass(ShopAuditDto dto) {
        // 参数校验
        // 修改店铺状态
        Shop shop = new Shop();
        shop.setState(ShopStateEnum.WAIT_ACTIVE.getCode());
        shop.setId(dto.getShopId());
        shopMapper.update(shop);
        // 添加审核日志
        ShopAuditLog log = new ShopAuditLog();
        log.setShopId(dto.getShopId());
        // TODO 目前没学登陆 我们先写死
        log.setAuditId(-1);
        log.setAuditTime(new Date());
        log.setNote(dto.getNote());
        auditLogMapper.add(log);
        // todo 发送邮件
        // 1.创建复杂邮件对象
        EmailUtil.sendEmail(dto.getShopId());
    }

    @Override
    public void activity(Long id) {
        // 修改店铺状态为已激活
        Shop shop = new Shop();
        shop.setState(2);
        shop.setId(id);
        shopMapper.update(shop);
    }

    private void save(ShopSettlementDto dto) {
        // 6.添加数据
        // 把dto的字段取出来赋值给shop对象
        Shop shop=  dto.getShop();
        shopMapper.add(shop);
        // 添加emp对象
        // 把dto中的字段取出来 赋值给emp对象
        Employee emp = dto.getEmp();
        emp.setShopId(shop.getId());
        employeeMapper.add(emp);
        // shop里面没有adminId
        Shop shop1 = new Shop();
        shop1.setId(shop.getId());
        shop1.setAdminId(emp.getId());
        shopMapper.update(shop1);
    }

    private void verify(ShopSettlementDto dto) {
        // 1.参数校验
        // 1.5手机号验证
//        Pattern p = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$"); // 验证手机号
//        Matcher m = p.matcher(dto.getAdmin().getPhone());
//        if (!m.matches()){
//            throw new BusinessException("用户手机号格式不正确！");
//        }
        // 2.两次密码是否一致
        ShopAdminDto admin = dto.getAdmin();
        if (!admin.getPassword().equals(admin.getComfirmPassword())) {
            throw new BusinessException("两次密码不一致！");
        }
        // 3.店铺是否注册过
        // 根据店铺名称去查询
        Shop shop = shopMapper.findByName(dto.getName());
        if (null != shop) {
            // 当前存在了该店铺
            throw new BusinessException("店铺已存在，请滚去登陆！");
        }
        // 4.当前管理员是否已经管理店铺
        // 根据用户名称去查询用户数据
        Employee employee = employeeMapper.findByName(admin.getUsername());
        if (null != employee && null != employee.getShopId()) { //他是店铺的人
            Shop shopTmp = shopMapper.findByAdminId(employee.getId());
            if (null != shopTmp) { // 这个人就是店长！
                throw new BusinessException("换个人！");
            }
        }
        // 5. 百度AI审核
        if (!BaiduAuditUtils.TextCensor(dto.getName())){
            throw new BusinessException("店铺名称违规！");
        }
        if (!BaiduAuditUtils.ImgCensor(dto.getLogo())){
            throw new BusinessException("店铺logo违规！");
        }
    }

    @Override
    public PageList<Shop> queryByPage(BaseQuery query) {
        // 店铺的列表数据
        PageList<Shop> pageList = super.queryByPage(query);
        List<Shop> shops = pageList.getRows();
        /**
         * 根据店铺列表的数据 查询出来日志数据 然后将日志数据添加到店铺的对象中
         */
        // 0.店铺和日志的关系 是什么？1-n 关联关系的点在哪 ？ 店铺的id ======= 日志的店铺id
        // 1.拿出来店铺列表中的所有店铺id
        List<Long> shopIds = shops.stream().map(Shop::getId).collect(Collectors.toList());
        // 2.根据店铺id集合去查询所有的日志
       List<ShopAuditLog> logs =  auditLogMapper.findByShopIds(shopIds);
       // 3.我们先将logs 根据   分组 转成 map    key：shopId value：List<log>
        Map<Long, List<ShopAuditLog>> logMap = logs.stream().collect(Collectors.groupingBy(ShopAuditLog::getShopId));
        // 4.遍历shop集合 将 日志放入到shop对象下
        shops.stream().forEach(shop->{
            List<ShopAuditLog> logTems = logMap.get(shop.getId());
            shop.setAuditLogs(logTems);
        });
        // 套路：
            // 先获取到父级的集合
        // 根据父级的id集合查询出来所有的子级集合
        // 将子级集合根据父级的id进行分组 转成map
        // 遍历父级集合 使用map.get(父级的id)
        // 将子级放入到父级
        return pageList;
    }
}
